#include <crypto/sha1.h>
#include <string.h>
#include <printf.h>
#include <util.h>

/* Tests from RFC 2202, section 3 */

struct test {
	int inlen;
	char* input;
	int keylen;
	uint8_t key[64];
	uint8_t hash[20];
} tests[] = {
	/* Test case 1 */
	{ 8, "Hi There", 20,
	      { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
	        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b },
	      { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b,
	        0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00 } },
	/* Test case 2 */
	{ 28, "what do ya want for nothing?", 4,
		"Jefe",
	      { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74,
	        0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 } },
	/* Test case 5 */
	{ 20, "Test With Truncation", 20,
	      { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
	        0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
	      { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
	        0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 } },
	{ 0, NULL, 0, { 0 }, { 0 } }
};

void dump(uint8_t hash[20])
{
	for(int i = 0; i < 20; i++)
		tracef("%02X ", hash[i]);
	tracef("\n");
}

int printable(char* msg)
{
	char* p;

	for(p = msg; *p; p++)
		if(*p & 0x80 || *p < 0x20)
			return 0;

	return 1;
}

static void test(struct test* tp)
{
	int inlen = tp->inlen;
	char* input = tp->input;
	int klen = tp->keylen;
	uint8_t* key = tp->key;
	uint8_t* hash = tp->hash;
	uint8_t temp[20];

	hmac_sha1(temp, key, klen, input, inlen);

	if(!memcmp(hash, temp, 20))
		return;

	tracef("FAIL %s\n", tp->input);
	dump(hash);
	dump(temp);

	_exit(0xFF);
}

int main(void)
{
	struct test* tp;

	for(tp = tests; tp->input; tp++)
		test(tp);

	return 0;
}
